home *** CD-ROM | disk | FTP | other *** search
- ;**********************************************************************;
- ;* R A M D I S K *;
- ;*--------------------------------------------------------------------*;
- ;* Aufgabe : Dieses Programm ist ein Treiber fr eine 160KB *;
- ;* RAM-Disk. *;
- ;*--------------------------------------------------------------------*;
- ;* Autor : MICHAEL TISCHER *;
- ;* entwickelt am : 4.08.1987 *;
- ;* letztes Update : 2.11.1991 *;
- ;*--------------------------------------------------------------------*;
- ;* assemblieren : MASM RAMDISK; *;
- ;* LINK RAMDISK; *;
- ;* EXE2BIN RAMDISK RAMDISK.SYS oder *;
- ; *;
- ;* TASM RAMDISK *;
- ;* LINK RAMDISK; *;
- ;* EXE2BIN RAMDISK RAMDISK.SYS *;
- ;*--------------------------------------------------------------------*;
- ;* Aufruf : In das Hauptverzeichnis kopieren, den Befehl *;
- ;* DEVICE=RAMDISK.SYS in die Datei CONFIG.SYS *;
- ;* aufnehmen und dann System booten. *;
- ;**********************************************************************;
-
- code segment
-
- assume cs:code,ds:code,es:code,ss:code
-
- org 0 ;Programm hat keinen PSP daher Anfang
- ;an der Offsetadresse 0
-
- ;== Konstanten =========================================================
-
- befehl equ 2 ;Offset Befehls-Feld im Datenblock
- status equ 3 ;Offset Status-Feld im Datenblock
- anz_ger equ 13 ;Offset Anzahl untersttzter Gerte
- wechsel equ 14 ;Offset Medium gewechselt?
- end_adr equ 14 ;Offset Treiber End-Adr. im Datenblock
- p_adr equ 14 ;Offset Puffer-Adresse im Datenblock
- anz_bef equ 16 ;die Funktionen 0-16 werden untersttzt
- anzahl equ 18 ;Offset Anzahl im Datenblock
- bpb_adr equ 18 ;Offset Adresse des BPB des Medium
- sektor equ 26 ;Offset erste Sektornummer
- ger_bez equ 22 ;Offset Gerte-Bezeichnung der RAMDisk
-
- ;== Daten ==============================================================
-
- erst_b equ this byte ;dies ist das erste Byte des Treibers
-
- ;-- Kopf des Gerte-Treibers -------------------------------------------
-
- dw -1,-1 ;Verbindung zum nchsten Treiber
- dw 0100100000000000b ;Treiber Attribut
- dw offset strat ;Pointer auf Strategie-Routine
- dw offset intr ;Pointer auf Interrupt-Routine
- db 1 ;ein Gert wird untersttzt
- db 7 dup (0) ;diese Bytes geben sonst den Namen an
-
- ;-- Sprungtabelle fr die einzelnen Funktionen -------------------------
-
- fkt_tab dw offset init ;Funktion 0: Initialisierung
- dw offset med_test ;Funktion 1: Medium Test
- dw offset get_bpb ;Funktion 2: Erstelle BPB
- dw offset lesen ;Funktion 3: direktes Lesen
- dw offset lesen ;Funktion 4: Lesen
- dw offset dummy ;Funktion 5: Lesen, im Puffer bleiben
- dw offset dummy ;Funktion 6: Eingabe-Status
- dw offset dummy ;Funktion 7: Lsche Eingabe-Puffer
- dw offset schreibe ;Funktion 8: Schreiben
- dw offset schreibe ;Funktion 9: Schreiben & Verifizieren
- dw offset dummy ;Funktion 10: Ausgabe-Status
- dw offset dummy ;Funktion 11: Lschen Ausgabe-Puffer
- dw offset schreibe ;Funktion 12: direktes Schreiben
- dw offset dummy ;Funktion 13: ffnen (diese Fkt ab 3.0)
- dw offset dummy ;Funktion 14: Schlieáen
- dw offset no_rem ;Funktion 15: wechselbares Medium?
- dw offset schreibe ;Funktion 16: Ausgabe bis beschftigt
-
- db_ptr dw (?),(?) ;Adresse des bergebenen Datenblocks
- rd_seg dw (?) ;RD_SEG:0000 ist der Anfang der RAMDisk
-
- bpb_ptr dw offset bpb,(?) ;Nimmt die Adresse des BPB auf
-
- boot_sek db 3 dup (0) ;hier befindet sich noramlerweise ein
- ;Sprungbefehl zur Boot-Routine
- db "MITI 1.0" ;Herstellername & Versionsnummer
- bpb dw 512 ;512 Bytes pro Sektor
- db 1 ;1 Sektoren pro Cluster
- dw 1 ;1 reservierter Sektor (Boot-Sektor)
- db 1 ;1 File-Allocation-Table (FAT)
- dw 64 ;maximal 64 Eintrge im Hauptverz.
- dw 320 ;insgesamt 320 Sektoren = 160 KB
- db 0FEh ;Media Descriptor (1 Seite mit 40
- ;Spuren zu je 8 Sektoren)
- dw 1 ;jede FAT belegt einen Sektor
-
- ;-- die Boot-Routine entfllt, da man ein System nicht ------
- ;-- von einer RAM-Disk booten kann
-
- vol_name db "RAMDISK " ;der eigentliche Volume-Name
- db 8 ;Attribut, definiert Volume-Name
-
- ;== Routinen und Funktionen des Treibers ===============================
-
- strat proc far ;Strategie-Routine
-
- mov cs:db_ptr,bx ;Adresse des Datenblocks in der
- mov cs:db_ptr+2,es ;Variable DB_PTR merken
-
- ret ;zurck zum Aufrufer
-
- strat endp
-
- ;-----------------------------------------------------------------------
-
- intr proc far ;Interrupt-Routine
-
- push ax ;Register auf Stack sichern
- push bx
- push cx
- push dx
- push di
- push si
- push bp
- push ds
- push es
- pushf ;auch das Flag-Register merken
-
- push cs ;Datensegment-Register setzen
- pop ds ;Code ist hier mit Daten identisch
-
- les di,dword ptr db_ptr;Adresse des Datenblock nach ES:DI
- mov bl,es:[di+befehl] ;Befehls-Code holen
- cmp bl,anz_bef ;ist Befehls-Code erlaubt?
- jle bc_ok ;JA --> bc_ok
-
- mov ax,8003h ;Code fr "unbekannter Befehl"
- jmp short intr_end ;zurck zum Aufrufer
-
- ;-- Befehls-Code war o.k. --> Befehl ausfhren ----------------
-
- bc_ok: shl bl,1 ;Pointer in Sprungtabelle errechnen
- xor bh,bh ;BH lschen
- call [fkt_tab+bx] ;Funktion aufrufen
-
- ;-- Ausfhrung der Funktion beendet ---------------------------
-
- intr_end label near
- push cs ;Datensegment-Register setzen
- pop ds ;Code ist hier mit Daten identisch
-
- les di,dword ptr db_ptr;Adresse des Datenblock nach ES:DI
- or ax,0100h ;Fertig-Bit setzen
- mov es:[di+status],ax ;das ganze im Status-Feld abspeichern
-
- popf ;Flag-Register zurckholen
- pop es ;andere Register zurckholen
- pop ds
- pop bp
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
-
- ret ;zurck zum Aufrufer
-
- intr endp
-
- ;-----------------------------------------------------------------------
-
- init proc near ;Initialisierungs-Routine
-
- ;-- der folgende Code wird nach der Installation --------------
- ;-- von der eigentlichen RAMDisk berschrieben
-
- ;-- Gertebezeichnung der RAMDisk ermitteln -------------------
-
- mov ah,30h ;DOS Version mit Hilfer der Fkt. 30(h)
- int 21h ;des DOS-Interrupt 21(h) abfragen
- cmp al,3 ;ist Version 3 oder hher?
- jb prinm ;JA --> PRINM
-
- mov al,es:[di+ger_bez] ;Gertebezeichnung holen
- add al,"A" ;in Buchstaben umwandeln
- mov im_ger,al ;in Installations-Meldung abspeichern
-
- prinm: mov dx,offset initm ;Adresse der Installations-Meldung
- mov ah,9 ;Funktionsnummer fr String ausgeben
- int 21h ;DOS-Interrupt aufrufen
-
- ;-- Adresse des ersten Bytes hinter der RAMDisk berechen ------
- ;-- und als Endadresse des Treibers setzen
-
- mov word ptr es:[di+end_adr],offset ramdisk+8000h
- mov ax,cs ;die RAM-Disk ist 32KB plus
- add ax,2000h ;2 * 64KB groá
- mov es:[di+end_adr+2],ax
- mov byte ptr es:[di+anz_ger],1 ;1 Gert wird unterst.
- mov word ptr es:[di+bpb_adr],offset bpb_ptr ;Adresse des BPB-
- mov es:[di+bpb_adr+2],ds ;Pointer
-
- mov ax,cs ;Segmentadresse des Beginn der RAMDisk
- mov bpb_ptr+2,ds ;Segmentadresse der BPB in BPB-Pointer
- mov dx,offset ramdisk ;zur Offsetadresse 0 berechnen
- mov cl,4 ;Offsetadresse durch 16 teilen und da-
- shr dx,cl ;durch in Segmentadresse umrechnen
- add ax,dx ;die beiden Segmentadressen addieren
- mov rd_seg,ax ;und merken
-
- ;-- Boot-Sektor anlegen ---------------------------------------
-
- mov es,ax ;Segmentadresse nach ES transferieren
- xor di,di ;Boots. beginnt mit dem 1. Byte der RD
- mov si,offset boot_sek ;Adresse des Boot-Sektor im Speicher
- mov cx,15 ;nur die ersten 15 Words werden genutzt
- rep movsw ;Boot-Sektor in RAMDisk kopieren
-
- ;-- die FAT anlegen -------------------------------------------
-
- mov di,512 ;FAT beginnt mit dem Byte 512 der RD
- mov al,0FEh ;Media-Descriptor in das erste Byte der
- stosb ;FAT schreiben
- mov ax,0FFFFH ;Code fr die Bytes 2 und 3 der FAT
- stosw ;in FAT abpspeichern
- mov cx,236 ;die restlichen 236 Word belegt die FAT
- inc ax ;AX auf 0 setzen
- rep stosw ;alle FAT-Eintrge auf unbelegt setzen
-
- ;-- das Hauptverzeichnis mit Volume-Namen anlegen -------------
-
- mov di,1024 ;das Hauptverz. beginnt im 3. Sektor
- mov si,offset vol_name ;Adresse des Volume-Namen im Speicher
- mov cx,6 ;der Volume-Name ist 6 Words lang
- rep movsw ;Volume-Namen in RD kopieren
-
- mov cx,1017 ;den Rest des Directories in den Sektoren
- xor ax,ax ;2, 3, 4 und 5 mit Nullen fllen
- rep stosw
-
- xor ax,ax ;alles o.k.
- ret ;zurck zum Aufrufer
-
- init endp
-
- ;-----------------------------------------------------------------------
-
- dummy proc near ;diese Routine bewirkt nichts
-
- xor ax,ax ;Beschftigt-Bit lschen
- ret ;zurck zum Aufrufer
-
- dummy endp
-
- ;-----------------------------------------------------------------------
-
- med_test proc near ;das Medium der RAM-Disk kann nicht ge-
- ;wechselt werden
-
- mov byte ptr es:[di+wechsel],1
- xor ax,ax ;Beschftigt-Bit lschen
- ret ;zurck zum Aufrufer
-
- med_test endp
-
- ;-----------------------------------------------------------------------
-
- get_bpb proc near ;Adresse des BPB an DOS bergeben
-
- mov word ptr es:[di+bpb_adr],offset bpb
- mov word ptr es:[di+bpb_adr+2],ds
-
- xor ax,ax ;Beschftigt-Bit lschen
- ret ;zurck zum Aufrufer
-
- get_bpb endp
-
- ;-----------------------------------------------------------------------
-
- no_rem proc near ;eine RAMDisk kann nicht gewechselt
- ;werden
-
- mov ax,20 ;Beschftigt-Bit setzen
- ret ;zurck zum Aufrufer
-
- no_rem endp
-
- ;-----------------------------------------------------------------------
-
- schreibe proc near
-
- xor bp,bp ;bertragung DOS --> RAMDisk
- jmp short move ;Daten kopieren
-
- schreibe endp
-
- ;-----------------------------------------------------------------------
-
- lesen proc near
-
- mov bp,1 ;bertragung RAMDisk --> DOS
-
- lesen endp
-
- ;-- MOVE: eine bestimmte Anzahl Sektoren zwischen RD und DOS verschieben
- ;-- Eingabe : BP = 0 : vom DOS zur RD bertragen (schreiben)
- ;-- 1 : von RD zum DOS bertragen (lesen)
- ;-- Ausgabe : keine
- ;-- Register : AX, BX, CX, DX, SI, DI, ES, DS und FLAGS werden verndert
- ;-- Info : die bentigten Informationen (Anzahl, erster Sektor)
- ;-- entnimmt diese Funktion dem vom DOS bergebenen Datenbl.
-
- move proc near
-
- mov bx,es:[di+anzahl] ;Anzahl der Sektoren lesen
- mov dx,es:[di+sektor] ;Nummer des ersten Sektors
- les di,es:[di+p_adr] ;Adresse des Puffers nach ES:DI
-
- move_1: or bx,bx ;noch Sektoren lesen?
- je move_e ;kein Sektor mehr --> ENDE
- mov ax,dx ;Sektornummer nach AX
- mov cl,5 ;Anzahl der Paragraphen (Segmentein-
- shl ax,cl ;heiten) durch Multiplikation mit 32
- ;berechnen
- add ax,cs:rd_seg ;und zum Segmentanfang der RD addieren
- mov ds,ax ;nach DS bertragen
- xor si,si ;Offsetadresse ist 0
- mov ax,bx ;Anzahl zu lesende Sektoren nach AX
- cmp ax,128 ;noch mehr als 128 Sektoren lesen
- jbe move_2 ;NEIN --> alle Sektoren lesen
- mov ax,128 ;JA --> 128 Sektoren (64 KB) lesen
- move_2: sub bx,ax ;Anzahl der gelesenen Sektoren abziehen
- add dx,ax ;auf nchsten zu lesenden Sek. addieren
- mov ch,al ;Anzahl zu lesende Sektoren * 256 Words
- xor cl,cl ;Lo-Byte des Word-Zhler auf 0 setzen
- or bp,bp ;soll gelesen werden?
- jne move_3 ;NEIN --> MOVE_3
- mov ax,es ;ES in AX merken
- push ds ;DS auf dem Stack merken
- pop es ;als ES zurckholen
- mov ds,ax ;ES und DS sind damit vertauscht
- xchg si,di ;und SI und DI vertauschen
- move_3: rep movsw ;Daten in den DOS-Puffer kopieren
- or bp,bp ;soll gelesen werden?
- jne move_1 ;NEIN --> evtl. weitere Sek. kopieren
- mov ax,es ;ES in AX merken
- push ds ;DS auf dem Stack merken
- pop es ;als ES zurckholen
- mov ds,ax ;ES und DS sind damit vertauscht
- xchg si,di ;und SI und DI wieder zurcktauschen
- jmp short move_1 ;evtl. weitere Sektoren kopieren
-
- move_e: xor ax,ax ;alles o.k.
- ret ;zurck zum Aufrufer
-
- move endp
-
- ;-- ab hier beginnt die eigentliche RAMDisk ----------------------------
-
- org ($-erst_b) + 16 - (($-erst_b) mod 16)
-
- ramdisk equ this byte
-
- initm db "**** 160 KB RAMDISK als Laufwerk "
- im_ger db "?"
- db ": installiert. (c) 1987,1991 by MICHAEL TISCHER$",13,10,10
-
- ;-----------------------------------------------------------------------
-
- code ends
- end